﻿using Microsoft.VisualBasic.Devices;
using NAudio.Wave;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;

namespace 摸鱼
{
    internal static class 声音
    {
        private static readonly object 锁 = new();
        private static WaveOutEvent 播放器;
        private static readonly ConcurrentDictionary<string, AudioFileReader> 音频缓存 = new();
        private static readonly List<WaveOutEvent> 活跃播放器列表 = new();

        // 添加声音设备检测状态
        private static bool? _有声音设备 = null;
        private static readonly object 设备检测锁 = new();

        public static void 其他(string 文件名, float 音量 = 1, int 播放时间 = 0, bool 多线程 = false)
        {
            var 文件路径 = $"{Environment.CurrentDirectory}/声音/{文件名}";

            if (多线程)
            {
                Task.Run(() => 播放内部(文件路径, 音量, 播放时间));
            }
            else
            {
                播放内部(文件路径, 音量, 播放时间);
            }
        }

        public static void 警报(float 音量 = 1, int 播放时间 = 0, bool 多线程 = false)
        {
            播放指定声音("普通.WAV", 音量, 播放时间, 多线程);
        }

        public static void 已开始(float 音量 = 1, int 播放时间 = 0, bool 多线程 = false)
        {
            播放指定声音("已开始.WAV", 音量, 播放时间, 多线程);
        }

        public static void 开始(float 音量 = 1, int 播放时间 = 0, bool 多线程 = false)
        {
            播放指定声音("开始.WAV", 音量, 播放时间, 多线程);
        }

        public static void 结束(float 音量 = 1, int 播放时间 = 0, bool 多线程 = false)
        {
            播放指定声音("结束.WAV", 音量, 播放时间, 多线程);
        }

        public static void 暂停(float 音量 = 1, int 播放时间 = 0, bool 多线程 = false)
        {
            播放指定声音("暂停.WAV", 音量, 播放时间, 多线程);
        }

        private static void 播放指定声音(string 文件名, float 音量, int 播放时间, bool 多线程)
        {
            var 文件路径 = $"{Environment.CurrentDirectory}/声音/{文件名}";

            if (多线程)
            {
                Task.Run(() => 播放内部(文件路径, 音量, 播放时间));
            }
            else
            {
                播放内部(文件路径, 音量, 播放时间);
            }
        }

        public static void 初始化()
        {
            // 预加载常用音频文件到缓存
            预加载音频("开始.WAV");
            预加载音频("结束.WAV");
            预加载音频("已开始.WAV");
            预加载音频("普通.WAV");
            预加载音频("暂停.WAV");

            // 初始化时检测声音设备
            检测声音设备();
        }

        // 检测声音设备的方法
        private static bool 检测声音设备()
        {
            lock (设备检测锁)
            {
                if (_有声音设备.HasValue)
                    return _有声音设备.Value;

                try
                {
                    // 尝试枚举可用的声音设备
                    var 设备数量 = WaveOut.DeviceCount;
                    if (设备数量 == 0)
                    {
                        Console.WriteLine("未检测到可用的声音设备");
                        _有声音设备 = false;
                        return false;
                    }

                    // 进一步测试是否能创建播放器
                    using (var 测试播放器 = new WaveOutEvent())
                    {
                        // 使用一个空的提供者来测试
                        var 空提供者 = new EmptyWaveProvider();
                        {
                            测试播放器.Init(空提供者);
                            // 如果能成功初始化，说明有可用的声音设备
                            _有声音设备 = true;
                            Console.WriteLine($"检测到 {设备数量} 个声音设备");
                            return true;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"声音设备检测失败: {ex.Message}");
                    _有声音设备 = false;
                    return false;
                }
            }
        }

        // 空的WaveProvider用于设备检测
        private class EmptyWaveProvider : IWaveProvider
        {
            public WaveFormat WaveFormat => WaveFormat.CreateIeeeFloatWaveFormat(44100, 2);

            public int Read(byte[] buffer, int offset, int count)
            {
                // 返回静音
                Array.Clear(buffer, offset, count);
                return count;
            }
        }

        private static void 预加载音频(string 文件名)
        {
            var 文件路径 = $"{Environment.CurrentDirectory}/声音/{文件名}";
            if (File.Exists(文件路径) && !音频缓存.ContainsKey(文件路径))
            {
                try
                {
                    var 音源 = new AudioFileReader(文件路径);
                    音频缓存[文件路径] = 音源;
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"预加载音频失败: {文件路径}, 错误: {ex.Message}");
                }
            }
        }

        private static AudioFileReader 获取或创建音源(string 文件路径)
        {
            if (音频缓存.TryGetValue(文件路径, out var 缓存的音源))
            {
                // 重置位置以便重新播放
                缓存的音源.Position = 0;
                return 缓存的音源;
            }

            // 如果不在缓存中，创建新的
            return new AudioFileReader(文件路径);
        }

        private static void 播放内部(string 文件路径, float 音量, int 播放时间)
        {
            // 检查声音设备
            if (!检测声音设备())
            {
                Console.WriteLine($"无声音设备，跳过播放: {文件路径}");
                return;
            }

            if (!File.Exists(文件路径))
            {
                Console.WriteLine($"音频文件不存在: {文件路径}");
                return;
            }

            AudioFileReader 音源 = null;
            WaveOutEvent 独立播放器 = null;

            try
            {
                音源 = 获取或创建音源(文件路径);

                // 使用独立的WaveOutEvent实例，避免共享实例的问题
                独立播放器 = new WaveOutEvent();
                独立播放器.DesiredLatency = 200; // 设置合适的延迟
                独立播放器.NumberOfBuffers = 3;  // 增加缓冲区数量

                lock (锁)
                {
                    活跃播放器列表.Add(独立播放器);
                }

                独立播放器.Init(音源);
                独立播放器.Volume = 音量;
                独立播放器.Play();

                // 如果指定了播放时间，设置定时停止
                if (播放时间 > 0)
                {
                    Task.Delay(播放时间).ContinueWith(_ =>
                    {
                        try
                        {
                            if (独立播放器 != null && 独立播放器.PlaybackState == PlaybackState.Playing)
                            {
                                独立播放器.Stop();
                            }
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine($"停止播放器时出错: {ex.Message}");
                        }
                    });
                }

                // 等待播放完成，但有超时保护
                var 开始时间 = DateTime.Now;
                var 超时时间 = TimeSpan.FromSeconds(30); // 30秒超时

                while (独立播放器.PlaybackState == PlaybackState.Playing)
                {
                    if (DateTime.Now - 开始时间 > 超时时间)
                    {
                        Console.WriteLine($"播放超时，强制停止: {文件路径}");
                        独立播放器.Stop();
                        break;
                    }
                    Thread.Sleep(50);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"播放音频失败: {文件路径}, 错误: {ex.Message}");

                // 如果播放失败，标记为无声音设备
                lock (设备检测锁)
                {
                    _有声音设备 = false;
                }
            }
            finally
            {
                if (独立播放器 != null)
                {
                    try
                    {
                        lock (锁)
                        {
                            活跃播放器列表.Remove(独立播放器);
                        }
                        独立播放器.Dispose();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"释放播放器时出错: {ex.Message}");
                    }
                }

                // 如果不是缓存的音源，则释放
                if (音源 != null && !音频缓存.Any(kvp => kvp.Value == 音源))
                {
                    try
                    {
                        音源.Dispose();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"释放音源时出错: {ex.Message}");
                    }
                }
            }
        }

        public static void 清理()
        {
            lock (锁)
            {
                // 停止所有活跃的播放器
                foreach (var 播放器 in 活跃播放器列表.ToList()) // 使用ToList避免修改集合
                {
                    try
                    {
                        if (播放器.PlaybackState == PlaybackState.Playing)
                        {
                            播放器.Stop();
                        }
                        播放器.Dispose();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"清理播放器时出错: {ex.Message}");
                    }
                }
                活跃播放器列表.Clear();

                // 清理音频缓存
                foreach (var 音源 in 音频缓存.Values)
                {
                    try
                    {
                        音源.Dispose();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"清理音源时出错: {ex.Message}");
                    }
                }
                音频缓存.Clear();
            }
        }

        // 原有的播放方法保持兼容性
        public static void 播放(AudioFileReader 音源, float 音量, int 时长)
        {
            if (音源 == null) return;

            // 检查声音设备
            if (!检测声音设备())
            {
                Console.WriteLine("无声音设备，跳过播放");
                return;
            }

            try
            {
                using (var 独立播放器 = new WaveOutEvent())
                {
                    独立播放器.DesiredLatency = 200;
                    独立播放器.NumberOfBuffers = 3;

                    独立播放器.Init(音源);
                    独立播放器.Volume = 音量;
                    独立播放器.Play();

                    if (时长 > 0)
                    {
                        Task.Delay(时长).ContinueWith(_ =>
                        {
                            try
                            {
                                if (独立播放器.PlaybackState == PlaybackState.Playing)
                                {
                                    独立播放器.Stop();
                                }
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine($"停止播放器时出错: {ex.Message}");
                            }
                        });
                    }

                    // 添加超时保护
                    var 开始时间 = DateTime.Now;
                    var 超时时间 = TimeSpan.FromSeconds(30);

                    while (独立播放器.PlaybackState == PlaybackState.Playing)
                    {
                        if (DateTime.Now - 开始时间 > 超时时间)
                        {
                            Console.WriteLine("播放超时，强制停止");
                            独立播放器.Stop();
                            break;
                        }
                        Thread.Sleep(50);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"播放音频失败: {ex.Message}");

                // 如果播放失败，标记为无声音设备
                lock (设备检测锁)
                {
                    _有声音设备 = false;
                }
            }
        }
    }
}